var debug = require('debug')('westmarket')
var koa = require('koa')
var app = koa()

// 错误处理
require('koa-onerror')(app)

// 错误处理
app.use(function *(next) {
    var ctx = this
    var _render = function *(status, message, dir) {
        var accept = ctx.accept.headers.accept
        if(accept && accept.indexOf('application/json')!=-1){
            ctx.body = {
                code: status,
                message: message
            }
        }else{
            yield ctx.render(dir, {
                message: message,
                code: status
            })
        }
    }

    try{
        yield next
    }catch(err){
        console.error(err.stack)
        return yield _render(500, '服务器繁忙', 'error/500')
    }

    var status = ctx.status || 500

    if(404 === status){
        return yield _render(404, '你要的页面没有找到', 'error/404')
    }else if(403 === status){
        return yield _render(403, '服务器拒绝执行', 'error/403')
    }else if(400 === status){
        return yield _render(400, '无效的请求', 'error/400')
    }else if(500 === status){
        return yield _render(500, '服务器繁忙', 'error/500')
    }else if(401 === status){
        return yield _render(401, '请先登录', 'login')
    }else{
        return false
    }

})

//log记录
app.use(require('koa-logger')())

// 装载配置文件
var config = require('./config')
app.use(function *(next) {
    if (!this.config) {
        this.config = config
    }
    yield next
})

// session
app.keys = ['secret', 'cento thanatos']
app.use(require('koa-session')(app))

// 模板引擎
var render = require('koa-views')
app.use(render(config.dir.views, {default: "jade"}))

//post body 解析
app.use(require('koa-body')({
    multipart:true,
    formidable: {
        multiples: true,
        keepExtensions: true,
        maxFieldsSize: 10 * 1024 * 1024,
        encoding: 'utf-8'
    }
}))

//mysql
var wrapper = require('co-mysql')
var mysql = require('mysql')
var pool = mysql.createPool(config.mysql)

// mysql method decorate
app.use(function *(next) {
    var ctx = this
    ctx.database = wrapper(pool).query
    ctx.db = function (sql, args) {
        var query = wrapper(pool).query
        this.insert = function *() {
            var results = yield query(sql, args)
            return results.insertId
        }
        this.execute = function *() {
            return yield query(sql, args)
        }
        this.unique = function *() {
            var results = yield this.execute()
            if(!results || results.length<=0){
                return null
            }
            if(Array.isArray(results)){
                return results[0]
            }else return results
        }
        this.list = function *() {
            var results = yield this.execute()
            if(results.length == 1){
                var obj = results[0]
                var setNull = true
                for(var key in obj){
                    if(obj[key]){
                        setNull = false
                        break
                    }
                }
                if(setNull){
                    return []
                }
            }
            return results
        }
        this.count = function *() {
            var results = yield this.execute()
            return results[0]['COUNT(*)']
        }
        return this
    }
    yield next
})

//静态文件
var staticCache = require('koa-static-cache');
app.use(staticCache(config.dir.static, {
    //maxAge: 604800000, // 7 days
    maxAge: 0,
    dynamic: true,
    gzip: true
}))

//静态文件加载
var combo = require("koa-combo")
app.use(combo([config.dir.static]))

// ---权限拦截
app.use(function *(next) {
    var ctx = this
    if (ctx.request.url.startsWith('/user/private') && (!ctx.session.user || !ctx.session.user.id)) {
        ctx.status = 401
        return
    }
    if(ctx.request.url.startsWith('/admin')){
        if(!ctx.session.admin || !ctx.session.admin.id){
            ctx.status = 404
            return
        }
    }
    yield next
})

// 渲染装饰模式
app.use(function *(next){
    var ctx = this
    ctx._render = function *(path, opts) {
        opts.login_user = ctx.session.user || null
        opts.path = ctx.path
        // ----user interceptor must be before it----
        if(ctx.request.url.startsWith('/user/private')){
            opts.user = ctx.session.user
        }else if(ctx.request.url.startsWith('/user')){
            opts.user = ctx.request.user
        }
        // ---- do the visitor considered the user ? -----
        if(ctx.request.url.startsWith('/user/private') || ctx.request.url.startsWith('/user')){
            opts.considered = false
            if(ctx.session.user && ctx.request.user.id != ctx.session.user.id){
                var count = yield ctx.db('SELECT COUNT(*) FROM Follow WHERE u_id=? AND o_id=?', [ctx.session.user.id, ctx.request.user.id]).count()
                opts.considered = count > 0
            }
        }
        if(ctx.request.url.startsWith('/admin')){
            opts.admin = ctx.session.admin
        }
        yield ctx.render(path, opts)
    }
    yield next
})

app.use(function *(next) {
    var ctx = this
    if (ctx.request.url.startsWith('/user/private') && (!ctx.session.user || !ctx.session.user.id)) {
        ctx.response.redirect('/login')
        return
    }
    yield next
})

//路由
var router = require('koa-router')()
app.use(router.routes())
require('./router/universal')(router)
require('./router/user')(router)
require('./router/recipe')(router)
require('./router/admin')(router)
require('./router/menu')(router)
require('./router/searcher')(router)

app.listen(config.port)
console.log('listening on port %s', config.port)

module.exports = app

//"host": "45.78.4.217",

//var dates = utils.YYYYMMDD(',').split(',')
//var dirname = path.join(path.resolve('static'), 'uploads', 'images', dates[0], dates[1], dates[2])
//filename = parseInt(Math.random()*100000000000000)+".jpg"
//
//var filepath = path.join(dirname, filename);
//var _path = ['/uploads', 'images', dates[0], dates[1], dates[2], filename].join('/');
//
//(function (_dirname) {
//    var callee = arguments.callee
//    var exists = fs.existsSync(_dirname)
//    if(!exists) {
//        var parent_dirname = path.dirname(_dirname)
//        callee(parent_dirname)
//        fs.mkdirSync(_dirname)
//    }
//})(dirname);
//
//return {
//    dirname: dirname,
//    filename: filename,
//    filepath: filepath,
//    path: _path
//}